package com.punch.course.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.punch.common.dto.course.CourseAuditDTO;
import com.punch.common.dto.course.CourseDTO;
import com.punch.common.dto.course.CourseLessonsDTO;
import com.punch.common.dto.user.user.RedisUserDTO;
import com.punch.common.enums.user.role.UserRoleEnum;
import com.punch.common.enums.user.user.AuditStatusEnum;
import com.punch.common.exception.BusinessException;
import com.punch.common.feign.FeignAreaService;
import com.punch.common.feign.FeignUserService;
import com.punch.common.page.PageInfo;
import com.punch.common.redis.utils.UserUtil;
import com.punch.common.tools.BasePage;
import com.punch.common.utils.BigDecimalUtil;
import com.punch.common.utils.ImageUtil;
import com.punch.common.vo.common.OptionVO;
import com.punch.common.vo.course.CourseContentVO;
import com.punch.common.vo.course.temp.CoursePageVO;
import com.punch.common.vo.course.temp.CourseVO;
import com.punch.common.vo.course.temp.SimpleCourseVO;
import com.punch.common.vo.user.user.UserExtendVO;
import com.punch.course.exception.CourseExceptionEnum;
import com.punch.course.mapper.CourseTempMapper;
import com.punch.course.model.*;
import com.punch.course.query.CourseQueryInfo;
import com.punch.course.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;

/**
 * <p>
 * 课程模板表 服务实现类
 * </p>
 *
 * @author wjj
 * @since 2020-12-01
 */
@Service
@Slf4j
public class CourseTempServiceImpl extends ServiceImpl<CourseTempMapper, CourseTemp> implements CourseTempService {

    @Resource
    private FeignAreaService feignAreaService;

    @Resource
    private FeignUserService feignUserService;

    @Resource
    private CourseLessonsService courseLessonsService;

    @Resource
    private CourseExtendService courseExtendService;

    @Resource
    private CourseAuditLogService courseAuditLogService;

    @Resource
    @Deprecated
    private CourseService courseService;

    @Resource
    private GoodsService goodsService;

    @Resource
    private CourseImageService courseImageService;

    /**
     * 课程列表
     *
     * @param queryInfo 查询条件
     * @return PageInfo<CoursePageVO>
     */
    @Override
    public PageInfo<CoursePageVO> listCourse(CourseQueryInfo queryInfo) {
        RedisUserDTO loginUser = UserUtil.getLoginUser();
        //学校/机构查看自己的课程
        if (loginUser.getRoleId() == UserRoleEnum.ORGAN.getCode() || loginUser.getRoleId() == UserRoleEnum.SCHOOL.getCode()) {
            queryInfo.setCreateId(UserUtil.getLoginUserId());
        }
        queryInfo.setCurrentRoleId(loginUser.getRoleId());
        queryInfo.setCurrentAreaId(loginUser.getAreaId());
        return BasePage.queryBasePage(queryInfo, params -> this.getBaseMapper().queryCount(params),
                params -> {
                    List<CoursePageVO> retList = this.getBaseMapper().queryList(params);
                    retList.forEach(coursePageVO -> coursePageVO.setCourseHourPriceShow(BigDecimalUtil.getMoneyBigDecimal(coursePageVO.getCourseHourPrice())));
                    return retList;
                });
    }

    /**
     * 查询课程详情
     *
     * @param courseId 课程id
     * @return CourseVO
     */
    @Override
    public CourseVO getCourse(Long courseId) {
        CourseTemp courseEX = getById(courseId);
        Optional.ofNullable(courseEX).orElseThrow(() -> new BusinessException(CourseExceptionEnum.COURSE_DETAIL_FAIL_NULL));
        CourseVO courseVO = new CourseVO();
        BeanUtils.copyProperties(courseEX, courseVO);
        //适用年级 courseGrade
        if (StringUtils.isNotEmpty(courseEX.getCourseGrade())) {
            String[] courseGradeArray = courseEX.getCourseGrade().split(",");
            List<Integer> courseGradeList = new ArrayList<>();
            for (String courseGrade : courseGradeArray) {
                courseGradeList.add(Integer.valueOf(courseGrade));
            }
            courseVO.setCourseGrade(courseGradeList);
        }

        //课程类目id course_category_id 单独处理
        if (StringUtils.isNotEmpty(courseEX.getCourseCategoryId())) {
            String[] courseCategoryIdArray = courseEX.getCourseCategoryId().split(",");
            List<Long> courseCategoryIdkList = new ArrayList<>();
            for (String courseCategoryId : courseCategoryIdArray) {
                courseCategoryIdkList.add(Long.valueOf(courseCategoryId));
            }
            courseVO.setCourseCategoryId(courseCategoryIdkList);
        }

        //根据课程内容id查询对应的课程内容（可能有多条，用集合接收）
        QueryWrapper<CourseLessons> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CourseLessons::getCourseId, courseId);
        List<CourseLessons> contentList = courseLessonsService.list(queryWrapper);
        if (CollUtil.isNotEmpty(contentList)) {
            List<CourseContentVO> courseContentList = new ArrayList<>();
            contentList.forEach(punchCourseContent -> {
                CourseContentVO courseContentVO = new CourseContentVO();
                courseContentVO.setLessonsTitle(punchCourseContent.getLessonsTitle());
                courseContentVO.setLessonsContent(punchCourseContent.getLessonsContent());
                courseContentList.add(courseContentVO);
            });
            courseVO.setCourseContentList(courseContentList);
        }
        if (StrUtil.isNotEmpty(courseVO.getCourseImg())) {
            courseVO.setCourseImg(ImageUtil.addPrefix(courseVO.getCourseImg()));
        }
        //获取场地要求与课程介绍
        QueryWrapper<CourseExtend> courseExtendQueryWrapper = new QueryWrapper<>();
        courseExtendQueryWrapper.lambda().eq(CourseExtend::getCourseId, courseId);
        CourseExtend courseExtendEX = courseExtendService.getOne(courseExtendQueryWrapper);
        Optional.ofNullable(courseExtendEX).ifPresent(courseExtend -> {
            courseVO.setCourseSiteRequirements(courseExtend.getCourseSiteRequirements());
            courseVO.setCourseIntroduce(courseExtend.getCourseIntroduce());
        });
        //处理金额
        courseVO.setCourseHourPriceShow(BigDecimalUtil.getMoneyBigDecimal(courseEX.getCourseHourPrice()));
        //是否包含教具
        if (courseEX.getGoodsId() != 0L) {
            Goods goodsEX = goodsService.getById(courseEX.getGoodsId());
            Optional.ofNullable(goodsEX).orElseThrow(() -> new BusinessException(CourseExceptionEnum.GOODS_NOT_EXIST));
            courseVO.setGoodsFlag(1);
            courseVO.setGoodsId(goodsEX.getId());
            courseVO.setGoodsName(goodsEX.getGoodsName());
            courseVO.setGoodsPriceShow(BigDecimalUtil.getMoneyBigDecimal(goodsEX.getGoodsPrice()));
            courseVO.setBuyFlag(courseEX.getBuyFlag());
        } else {
            courseVO.setGoodsFlag(0);
        }
        //获取图片
        QueryWrapper<CourseImage> imageQueryWrapper = new QueryWrapper<>();
        imageQueryWrapper.lambda().eq(CourseImage::getCourseId, courseId);
        List<CourseImage> list = courseImageService.list(imageQueryWrapper);
        if (CollUtil.isNotEmpty(list)) {
            List<String> imageList = new ArrayList<>();
            list.forEach(t -> imageList.add(ImageUtil.addPrefix(t.getIntroduceImg())));
            courseVO.setImageList(imageList);
        }
        courseVO.setCourseId(courseId);
        return courseVO;
    }

    /**
     * 保存课程
     *
     * @param courseDTO 课程表单
     * @return 课程id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveCourse(CourseDTO courseDTO) {
        CourseTemp courseTemp = new CourseTemp();
        //保存课程基本信息
        BeanUtils.copyProperties(courseDTO, courseTemp);
        RedisUserDTO loginUser = UserUtil.getLoginUser();
        //当前用户地区id
        Integer currentUserAreaId = loginUser.getAreaId();
        //当前用户地区
        String currentUserAreaName = loginUser.getAreaName();
        //当前用户id
        Long currentUserId = loginUser.getUserId();
        //当前用户角色id
        Integer currentUserRoleId = loginUser.getRoleId();
        //获取用户名称
        String createName = loginUser.getUsername();
        courseTemp.setCreateId(currentUserId);
        courseTemp.setCreateName(createName);
        courseTemp.setAreaId(currentUserAreaId);
        String parentIds = feignAreaService.getParentIds(currentUserAreaId);
        courseTemp.setAllAreaId(parentIds + "," + currentUserAreaId);
        courseTemp.setAreaName(currentUserAreaName);
        if (currentUserRoleId == UserRoleEnum.SCHOOL.getCode()) {
            courseTemp.setType(1);
        }
        handlerGrade(courseTemp, courseDTO);
        //学校创建的课程直接审核通过
        if (currentUserRoleId == UserRoleEnum.SCHOOL.getCode()) {
            courseTemp.setCourseStatus(AuditStatusEnum.PASSED.getCode());
        }
        //处理封面图片
        if (StrUtil.isNotEmpty(courseDTO.getCourseImg())) {
            courseTemp.setCourseImg(ImageUtil.removePrefix(courseDTO.getCourseImg()));
        }
        //机构创建课程插入机构编号
        if (currentUserRoleId == UserRoleEnum.ORGAN.getCode()) {
            UserExtendVO orgExtend = feignUserService.getUserSettlement(currentUserId, 1).getData();
            courseTemp.setOrgNo(orgExtend.getOrgNo());
        }
        //处理金额
        courseTemp.setCourseHourPrice(BigDecimalUtil.getMoneyFee(courseDTO.getCourseHourPriceShow()));
        if (!save(courseTemp)) {
            throw new BusinessException(CourseExceptionEnum.COURSE_SAVE_FAIL);
        }
        Long courseId = courseTemp.getId();
        //保存课程扩展信息
        courseExtendService.saveCourseExtend(courseId, courseDTO.getCourseSiteRequirements(), courseDTO.getCourseIntroduce());
        //保存课节内容
        if (CollUtil.isNotEmpty(courseDTO.getCourseContentList())) {
            insertCourseContent(courseId, courseDTO.getCourseContentList());
        }
        //保存课程详情图片
        List<String> imageList = courseDTO.getImageList();
        if (CollUtil.isNotEmpty(imageList)) {
            courseImageService.saveIntroduceImg(courseId, imageList);
        }
        return courseId;
    }


    /**
     * 修改课程
     *
     * @param courseDTO 课程表单
     * @return 课程id
     */
    @Override
    public Long updateCourse(CourseDTO courseDTO) {
        Long courseId = courseDTO.getCourseId();
        CourseTemp courseTempEX = getById(courseId);
        if (courseTempEX == null) {
            throw new BusinessException(CourseExceptionEnum.COURSE_EDIT_FAIL);
        }
        CourseTemp courseTemp = new CourseTemp();
        //修改课程基本信息
        BeanUtils.copyProperties(courseDTO, courseTemp);
        //处理图片
        if (StrUtil.isNotEmpty(courseDTO.getCourseImg())) {
            courseTemp.setCourseImg(ImageUtil.removePrefix(courseDTO.getCourseImg()));
        } else {
            courseTemp.setCourseImg("");
        }
        //处理金额
        courseTemp.setCourseHourPrice(BigDecimalUtil.getMoneyFee(courseDTO.getCourseHourPriceShow()));
        if (courseDTO.getGoodsId() == null) {
            courseTemp.setGoodsId(0L);
        }
        courseTemp.setId(courseId);
        updateById(courseTemp);
        //删除课程内容信息（软删除）
        UpdateWrapper<CourseLessons> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(CourseLessons::getCourseId, courseDTO.getCourseId());
        courseLessonsService.remove(updateWrapper);
        if (CollUtil.isNotEmpty(courseDTO.getCourseContentList())) {
            insertCourseContent(courseId, courseDTO.getCourseContentList());
        }
        //修改课程扩展信息
        courseExtendService.updateCourseExtend(courseId, courseDTO.getCourseSiteRequirements(), courseDTO.getCourseIntroduce());
        //保存课程详情图片
        List<String> imageList = courseDTO.getImageList();
        courseImageService.updateIntroduceImg(courseId, imageList);
        return courseId;
    }

    /**
     * 删除课程
     *
     * @param courseId 课程id
     */
    @Override
    public void deleteCourse(Long courseId) {
        CourseTemp courseTempEX = getById(courseId);
        if (courseTempEX == null) {
            throw new BusinessException(CourseExceptionEnum.COURSE_DEL_FAIL_NULL);
        }
        removeById(courseId);
        //删除课节内容
        UpdateWrapper<CourseLessons> lessonsUpdateWrapper = new UpdateWrapper<>();
        lessonsUpdateWrapper.lambda().eq(CourseLessons::getCourseId, courseId);
        courseLessonsService.remove(lessonsUpdateWrapper);
        //删除课程扩展信息
        UpdateWrapper<CourseExtend> extendUpdateWrapper = new UpdateWrapper<>();
        extendUpdateWrapper.lambda().eq(CourseExtend::getCourseId, courseId);
        courseExtendService.remove(extendUpdateWrapper);
    }

    /**
     * 课程审核
     *
     * @param courseAuditDTO 审核表达
     */
    @Override
    public void auditCourse(CourseAuditDTO courseAuditDTO) {
        //当前登录用户角色id
        RedisUserDTO redisUserDTO = UserUtil.getLoginUser();
        Integer currentRoleId = redisUserDTO.getRoleId();
        CourseTemp courseTempEX = getById(courseAuditDTO.getCourseId());
        Optional.ofNullable(courseTempEX).orElseThrow(() -> new BusinessException(CourseExceptionEnum.COURSE_DETAIL_FAIL_NULL));
        verifyStatus(courseAuditDTO.getCourseStatus(), courseTempEX.getCourseStatus(), currentRoleId);
        CourseTemp courseTemp = new CourseTemp();
        courseTemp.setId(courseAuditDTO.getCourseId());
        //如果是机构,查看且没有审核成功,课程提交审核状态为(机构待审核提交),确保运营在课程列表查询不到该数据
        log.info(" redisUserDTO.getAuditStatus()：{}", redisUserDTO.getAuditStatus());
        if (currentRoleId.equals(UserRoleEnum.ORGAN.getCode()) && !redisUserDTO.getAuditStatus().equals(AuditStatusEnum.PASSED.getCode())) {
            courseTemp.setCourseStatus(AuditStatusEnum.ORG_UN_AUDIT_COMMIT.getCode());
        } else {
            courseTemp.setCourseStatus(courseAuditDTO.getCourseStatus());
        }
        log.info(" 课程信息：{}", courseTemp);
        updateById(courseTemp);
        fullAuditLog(courseAuditDTO);
    }

    /**
     * 获取审核内容
     *
     * @param courseId 课程id
     * @return string
     */
    @Override
    public String getCourseAuditMessage(Long courseId) {
        QueryWrapper<CourseAuditLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CourseAuditLog::getCourseId, courseId).orderByDesc(CourseAuditLog::getUpdateTime).last("limit 1");
        CourseAuditLog courseAuditLog = courseAuditLogService.getOne(queryWrapper);
        return courseAuditLog.getRemarks();
    }

    /**
     * 课程课节列表
     *
     * @param courseId 课程id
     * @return list
     */
    @Override
    public List<CourseContentVO> listCourseLessons(Long courseId) {
        List<CourseContentVO> courseContentList = new ArrayList<>();
        //根据课程内容id查询对应的课程内容（可能有多条，用集合接收）
        QueryWrapper<CourseLessons> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CourseLessons::getCourseId, courseId);
        List<CourseLessons> contentList = courseLessonsService.list(queryWrapper);
        if (CollUtil.isNotEmpty(contentList)) {
            contentList.forEach(punchCourseContent -> {
                CourseContentVO courseContentVO = new CourseContentVO();
                courseContentVO.setLessonsTitle(punchCourseContent.getLessonsTitle());
                courseContentVO.setLessonsContent(punchCourseContent.getLessonsContent());
                courseContentList.add(courseContentVO);
            });
        }
        return courseContentList;
    }

    /**
     * 处理老的课程表,上线以后删除
     */
    @Override
    public void handlerOldCourse() {
        List<PunchCourse> list = courseService.list();
        List<CourseTemp> insertList = new ArrayList<>();
        List<CourseExtend> extendList = new ArrayList<>();
        list.forEach(punchCourse -> {
            CourseTemp courseTemp = new CourseTemp();
            BeanUtil.copyProperties(punchCourse, courseTemp);
            courseTemp.setCourseHourPrice(BigDecimalUtil.getMoneyFee(punchCourse.getCourseHourPrice()));
            if (punchCourse.getRoleId() == UserRoleEnum.SCHOOL.getCode()) {
                courseTemp.setType(1);
            }
            insertList.add(courseTemp);

            CourseExtend courseExtend = new CourseExtend();
            courseExtend.setCourseId(punchCourse.getId());
            courseExtend.setCourseIntroduce(punchCourse.getCourseIntroduce());
            courseExtend.setCourseSiteRequirements(punchCourse.getCourseSiteRequirements());
            courseExtend.setCreateTime(punchCourse.getCreateTime());
            courseExtend.setUpdateTime(punchCourse.getUpdateTime());
            extendList.add(courseExtend);
        });
        saveBatch(insertList);
        courseExtendService.saveBatch(extendList);
        log.info("总共插入课程:{},课程扩展信息:{}", insertList.size(), extendList.size());
    }

    /**
     * 课程下拉列表
     *
     * @param courseName 课程名称
     * @return List<SimpleCourseVO>
     */
    @Override
    public List<SimpleCourseVO> listCourseSelect(String courseName) {
        Long createId = UserUtil.getLoginUser().getUserId();
        List<SimpleCourseVO> retList = getBaseMapper().listCourseSimple(courseName, createId);
        retList.forEach(simpleCourseVO -> {
            simpleCourseVO.setCourseHourPriceShow(BigDecimalUtil.getMoneyBigDecimal(simpleCourseVO.getCourseHourPrice()));
            simpleCourseVO.setGoodsPriceShow(simpleCourseVO.getGoodsPrice() == null ? BigDecimal.ZERO : BigDecimalUtil.getMoneyBigDecimal(simpleCourseVO.getGoodsPrice()));
            simpleCourseVO.setGoodsFlag(simpleCourseVO.getGoodsId() == 0L ? 0 : 1);//是否包含教具
        });
        return retList;
    }

    /**
     * 修改机构未审核状态下提交的课程
     *
     * @param orgId 机构id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUnAuditCommit(Long orgId) {
        getBaseMapper().updateUnAuditCommit(orgId);
    }

    /**
     * 地区下课程列表
     *
     * @param areaId 地区id
     * @return List<OptionVO < Integer>>
     */
    @Override
    public List<OptionVO<String>> listSimpleCourse(Integer areaId) {
        List<OptionVO<String>> retList = new ArrayList<>();
        QueryWrapper<CourseTemp> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().apply(" FIND_IN_SET({0},all_area_ids)", areaId);
        list(queryWrapper).forEach((t) -> {
            OptionVO<String> optionVO = new OptionVO<>();
            optionVO.setLabel(t.getCourseName());
            optionVO.setValue(String.valueOf(t.getId()));
            retList.add(optionVO);
        });
        return retList;
    }


    /**
     * 特殊处理  适用年级与上课周期
     *
     * @param courseTemp 课程实体
     * @param courseDTO  课程
     */
    private void handlerGrade(CourseTemp courseTemp, CourseDTO courseDTO) {
        //课程类目id 特殊处理
        if (CollUtil.isNotEmpty(courseDTO.getCourseCategoryId())) {
            StringBuilder sb = new StringBuilder();
            courseDTO.getCourseCategoryId().forEach(categoryId -> {
                sb.append(categoryId).append(",");
            });
            sb.deleteCharAt(sb.length() - 1);
            courseTemp.setCourseCategoryId(sb.toString());
        }
        //适用年级 courseGrade
        if (CollUtil.isNotEmpty(courseDTO.getCourseGrade())) {
            StringBuilder sb = new StringBuilder();
            courseDTO.getCourseGrade().sort(Comparator.naturalOrder());//排序下
            courseDTO.getCourseGrade().forEach(courseGrade -> sb.append(courseGrade).append(","));
            sb.deleteCharAt(sb.length() - 1);
            courseTemp.setCourseGrade(sb.toString());
        }
    }


    /**
     * 插入课程节数内容
     *
     * @param courseId          课程id
     * @param courseContentList 课程节数内容列表
     */
    private void insertCourseContent(Long courseId, List<CourseLessonsDTO> courseContentList) {
        List<CourseLessons> saveList = new ArrayList<>();
        //保存课程内容信息
        courseContentList.forEach(courseLessonsDTO -> {
            if (!StrUtil.isEmpty(courseLessonsDTO.getLessonsTitle()) || !StrUtil.isEmpty(courseLessonsDTO.getLessonsContent())) {
                CourseLessons punchCourse = new CourseLessons();
                punchCourse.setLessonsTitle(courseLessonsDTO.getLessonsTitle());
                punchCourse.setLessonsContent(courseLessonsDTO.getLessonsContent());
                punchCourse.setCourseId(courseId);
                saveList.add(punchCourse);
            }
        });
        courseLessonsService.saveBatch(saveList);
    }

    /**
     * 课程审核日志
     *
     * @param courseAuditDTO
     */
    private void fullAuditLog(CourseAuditDTO courseAuditDTO) {
        CourseAuditLog courseAuditLog = new CourseAuditLog();
        courseAuditLog.setAuditTime(LocalDateTime.now());
        courseAuditLog.setAuditStatus(courseAuditDTO.getCourseStatus());
        courseAuditLog.setCourseId(courseAuditDTO.getCourseId());
        courseAuditLog.setAuditor(UserUtil.getLoginUser().getUserId());
        courseAuditLog.setRemarks(courseAuditDTO.getRemarks());
        courseAuditLogService.save(courseAuditLog);
    }

    /**
     * @param newStatus     即将更改状态
     * @param oldStatus     本身状态
     * @param currentRoleId 当前用户角色id
     */
    private void verifyStatus(Integer newStatus, Integer oldStatus, Integer currentRoleId) {
        //判断当前用户是否是运营人员还是机构,机构只能提交教师 运营人员审核教师，需要做验证
//        if (!(currentRoleId == UserRoleEnum.EDUCATION.getCode()
//                || currentRoleId == UserRoleEnum.ORGAN.getCode())) {
//            throw new BusinessException(CourseExceptionEnum.AUDIT_ERROR.getCode(), "只有教育局/机构才能进行审核操作");
//        }
        //不做太多控制状态

        //2者一致,说明状态错误
        if (oldStatus.equals(newStatus)) {
            throw new BusinessException(CourseExceptionEnum.AUDIT_ERROR);
        }
//        //已经审核不能在审核
//        if (oldStatus == AuditStatusEnum.PASSED.getCode()) {
//            throw new BusinessException(UserExceptionEnum.AUDIT_ERROR.getCode(), "该机构已审核");
//        }
//
//        //0状态说明机构还没提交该老师
//        if (oldStatus == AuditStatusEnum.TO_AUDIT.getCode()) {
//            throw new BusinessException(UserExceptionEnum.AUDIT_ERROR.getCode(), "该机构暂未提交审核");
//        }
    }
}
